package com.foo.designpattern.composite.transparentcomposite;

import junit.framework.TestCase;

/**
 * com.foo.designpattern.composite.transparentcomposite
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-20 17:42.
 *
 * @Description 测试类：合成模式(Composite)--透明式的合成模式
 * <p/>
 * 合成模式：合成模式属于对象的结构模式，有时又叫做“部分-整体”模式。
 * 合成模式将对象组织到树结构中，可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复杂元素同等看待。
 * 合成模式的实现根据所实现接口的区别分为两种形式，分别成为安全式和透明式。
 * <p/>
 * 安全式的合成模式要求管理聚集的方法只出现在树枝构件类中，而不出现在树叶构件类中。
 * 与安全式的合成模式不同的是，透明式的合成模式要求所有的具体构件类，不论树枝还是树叶结构，均符合一个固定接口。
 * <p/>
 * 合成模式把部分和整体的关系用树结构表示出来。
 * 比如，一个文件系统(Windows文件系统或者Linux文件系统)就是一个典型的合成模式系统。
 * 文件系统是一个树结构，树上长有树叶节点。树的节点有两种，一种是树枝节点，即目录，有内部树结构；另一种是文件，即树叶节点，没有内部树结构。
 * 显然，可以把目录和文件当做同一种对象同等对待和处理，这也就是合成模式的应用。
 * <p/>
 * 合成模式可以不提供父对象的管理方法，但是合成模式必须在合适的地方提供子对象的管理方法，诸如：add()、remove()以及getChild()等。
 * <p/>
 * 本例是透明式的合成模式
 * 透明式的合成模式是指：从客户端使用合成模式上，是否需要区分到底是"树枝对象"还是"树叶对象"。
 * 如果是透明的，那就不用区分，对于客户而言，都是Component对象，具体的类型对于客户端而言是透明的，是无需关心的。
 * 对于合成模式而言，在安全性和透明性上，会更看重透明性，
 * 因为合成模式的目的是：让客户端不再区分操作的是树枝对象还是树叶对象，而是以一个统一的方式来操作。
 * 因此，在使用合成模式的时候，建议多采用透明式的合成模式。
 * <p/>
 * 合成模式总结：
 * 一般提到的合成模式是指透明式的合成模式(组合模式)。合成模式解耦了客户程序与复杂元素内部结构，
 * 从而使客户程序可以像处理简单元素一样来处理复杂元素。如果你想要创建层次结构，并可以在其中以相同的方式对待所有元素，
 * 那么合成模式就是最理想的选择。在本例中，通过对一个文件系统举例说明了合成模式的用户。在这个例子中，文件和目录都执行
 * 相同的接口，这就是组合模式的关键。通过执行相同的接口，你就可以以相同的方式对待文件和目录，从而实现将文件或目录储存为
 * 目录的子元素。
 * <p/>
 * 合成模式的优点：
 * 1、使客户端调用简单，客户端可以一致的使用组合结构或其中单个对象，
 * 用户就不必关心自己处理的是单个对象还是整个组合机构，这就简化了客户端代码。
 * 2、更容易管理对象构件，客户端不必因为加入了新的对象部件而更改代码。
 * <p/>
 * 合成模式的适用场景：
 * 1、你想表示对象的"部分-整体"层次结构；
 * 2、你希望用户忽略组合对象与单个对象的不同，用户将同一地使用组合结构中的所有对象。
 */

public class TransParentCompositeTestCase extends TestCase {
    public void testTransParentComposite() {
        System.out.println("= = = = ↓↓↓透明式合成模式，测试开始↓↓↓ = = = =");

        /**
         * 客户端无需区分操作的是树枝对象(Composite)还是树叶对象(Leaf)，
         * 对于客户端而言，操作的都是抽象构件(Component)对象。
         */
        Component root = new Composite("服装");
        Component component1 = new Composite("男装");
        Component component2 = new Composite("女装");

        Component leaf1 = new Leaf("衬衫");
        Component leaf2 = new Leaf("夹克");
        Component leaf3 = new Leaf("裙子");
        Component leaf4 = new Leaf("套装");

        root.addChild(component1);
        root.addChild(component2);
        component1.addChild(leaf1);
        component1.addChild(leaf2);
        component2.addChild(leaf3);
        component2.addChild(leaf4);

        root.printStructure("");

        System.out.println("= = = = ↑↑↑透明式合成模式，测试结束↑↑↑ = = = =");
    }
}
